home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ghostscript / src / zcspace2.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  284 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zcspace2.c */
  20. /* Level 2 color space operators for Ghostscript */
  21. #include "ghost.h"
  22. #include "errors.h"
  23. #include "oper.h"
  24. #include "gscolor.h"
  25. #include "gxcolor.h"
  26. #include "gscspace.h"
  27. #include "gscolor2.h"
  28. #include "dict.h"
  29. #include "dparam.h"
  30. #include "estack.h"
  31. #include "iname.h"        /* for name_eq */
  32. #include "state.h"
  33. #include "store.h"
  34.  
  35. /* Imported from gscolor2.c */
  36. extern const gs_color_space_type
  37.     gs_color_space_type_Separation,
  38.     gs_color_space_type_Indexed,
  39.     gs_color_space_type_Pattern;
  40.  
  41. /* Imported from zcie.c */
  42. extern int
  43.     zcolorspace_CIEBasedABC(P3(const ref *, gs_color_space *, ref_cie_procs *)),
  44.     zcolorspace_CIEBasedA(P3(const ref *, gs_color_space *, ref_cie_procs *));
  45.  
  46. /* Forward references */
  47. typedef enum { cs_allow_base, cs_allow_paint, cs_allow_all } cs_allowed;
  48. private int cspace_param(P4(const ref *, gs_color_space *, ref_color_procs *, cs_allowed));
  49.  
  50. /* Names of color spaces: */
  51. static ref color_space_names[8];
  52. #define name_DeviceGray color_space_names[(int)gs_color_space_index_DeviceGray]
  53. #define name_DeviceRGB color_space_names[(int)gs_color_space_index_DeviceRGB]
  54. #define name_DeviceCMYK color_space_names[(int)gs_color_space_index_DeviceCMYK]
  55. #define name_CIEBasedABC color_space_names[(int)gs_color_space_index_CIEBasedABC]
  56. #define name_CIEBasedA color_space_names[(int)gs_color_space_index_CIEBasedA]
  57. #define name_Separation color_space_names[(int)gs_color_space_index_Separation]
  58. #define name_Indexed color_space_names[(int)gs_color_space_index_Indexed]
  59. #define name_Pattern color_space_names[(int)gs_color_space_index_Pattern]
  60.  
  61. /* Initialization */
  62. private void
  63. zcspace2_init(void)
  64. {    static const names_def csn[] = {
  65.  
  66.     /* Create the names of the color spaces. */
  67.        { "DeviceGray", &name_DeviceGray },
  68.        { "DeviceRGB", &name_DeviceRGB },
  69.        { "DeviceCMYK", &name_DeviceCMYK },
  70.        { "CIEBasedABC", &name_CIEBasedABC },
  71.        { "CIEBasedA", &name_CIEBasedA },
  72.        { "Separation", &name_Separation },
  73.        { "Indexed", &name_Indexed },
  74.        { "Pattern", &name_Pattern },
  75.  
  76.     /* Mark the end of the initialized name list. */
  77.        names_def_end
  78.     };
  79.  
  80.     init_names(csn);
  81. }
  82.  
  83.  
  84. /* currentcolorspace */
  85. int
  86. zcurrentcolorspace(register os_ptr op)
  87. {    push(1);
  88.     if ( r_has_type(&istate.colorspace.array, t_null) )
  89.     {    /* Create the 1-element array on the fly. */
  90.         const gs_color_space *pcs = gs_currentcolorspace(igs);
  91.         make_tasv(op, t_array, a_readonly, 1, refs,
  92.               &color_space_names[(int)pcs->type->index]);
  93.     }
  94.     else
  95.         *op = istate.colorspace.array;
  96.     return 0;
  97. }
  98.  
  99. /* setcolorspace */
  100. int
  101. zsetcolorspace(register os_ptr op)
  102. {    gs_color_space cs;
  103.     ref_color_procs procs;
  104.     ref_colorspace cspace_old;
  105.     es_ptr ep = esp;
  106.     int code;
  107.     procs = istate.colorspace.procs;
  108.     code = cspace_param((const ref *)op, &cs, &procs, cs_allow_all);
  109.     if ( code < 0 )
  110.     {    esp = ep;
  111.         return code;
  112.     }
  113.     /* The color space installation procedure may refer to */
  114.     /* istate.colorspace.procs. */
  115.     cspace_old = istate.colorspace;
  116.     if ( r_has_type(op, t_name) )
  117.         make_null(&istate.colorspace.array);    /* no params */
  118.     else
  119.         istate.colorspace.array = *op;
  120.     istate.colorspace.procs = procs;
  121.     code = gs_setcolorspace(igs, &cs);
  122.     if ( code < 0 )
  123.     {    istate.colorspace = cspace_old;
  124.         esp = ep;
  125.         return code;
  126.     }
  127.     pop(1);
  128.     return (esp == ep ? 0 : o_push_estack);
  129. }
  130.  
  131. /* ------ Initialization procedure ------ */
  132.  
  133. op_def zcspace2_op_defs[] = {
  134.     {"0currentcolorspace", zcurrentcolorspace},
  135.     {"1setcolorspace", zsetcolorspace},
  136.     op_def_end(zcspace2_init)
  137. };
  138.  
  139. /* ------ Internal procedures ------ */
  140.  
  141. /* Dummy indexed lookup procedure. */
  142. private int
  143. null_indexed_lookup_proc(int index, float *values)
  144. {    return 0;
  145. }
  146.  
  147. /* Extract the parameters for a color space. */
  148. private int
  149. cspace_param(const ref *pcsref, gs_color_space *pcs,
  150.   ref_color_procs *pcprocs, cs_allowed allow)
  151. {    const ref *pcsa, *pcsn;
  152.     uint asize;
  153.     int csi;
  154.     int code;
  155.     if ( r_has_type(pcsref, t_array) )
  156.     {    check_read(*pcsref);
  157.         pcsa = pcsref->value.const_refs;
  158.         asize = r_size(pcsref);
  159.         if ( asize == 0 )
  160.             return_error(e_rangecheck);
  161.     }
  162.     else
  163.     {    pcsa = pcsref;
  164.         asize = 1;
  165.     }
  166.     pcsn = pcsa++;
  167.     asize--;
  168.     check_type(*pcsn, t_name);
  169.     for ( csi = 0; !name_eq(pcsn, &color_space_names[csi]); )
  170.     {    if ( ++csi == countof(color_space_names) )
  171.             return_error(e_rangecheck);
  172.     }
  173.     /* Note: to avoid having to undo allocations, we should make all */
  174.     /* checks before any recursive calls of cspace_params. */
  175.     /* Unfortunately, we can't do this in the case of Indexed spaces. */
  176.     switch ( (gs_color_space_index)csi )
  177.     {
  178.     case gs_color_space_index_DeviceGray:
  179.         if ( asize != 0 )
  180.             return_error(e_rangecheck);
  181.         pcs->type = &gs_color_space_type_DeviceGray;
  182.         break;
  183.     case gs_color_space_index_DeviceRGB:
  184.         if ( asize != 0 )
  185.             return_error(e_rangecheck);
  186.         pcs->type = &gs_color_space_type_DeviceRGB;
  187.         break;
  188.     case gs_color_space_index_DeviceCMYK:
  189.         if ( asize != 0 )
  190.             return_error(e_rangecheck);
  191.         pcs->type = &gs_color_space_type_DeviceCMYK;
  192.         break;
  193.     case gs_color_space_index_CIEBasedABC:
  194.         if ( asize != 1 )
  195.             return_error(e_rangecheck);
  196.         code = zcolorspace_CIEBasedABC(pcsa, pcs, &pcprocs->cie);
  197.         if ( code < 0 )
  198.             return code;
  199.         /*pcs->type = &gs_color_space_type_CIEBasedABC;*/    /* set by zcolorspace... */
  200.         break;
  201.     case gs_color_space_index_CIEBasedA:
  202.         if ( asize != 1 )
  203.             return_error(e_rangecheck);
  204.         code = zcolorspace_CIEBasedA(pcsa, pcs, &pcprocs->cie);
  205.         if ( code < 0 )
  206.             return code;
  207.         /*pcs->type = &gs_color_space_type_CIEBasedA;*/    /* set by zcolorspace... */
  208.         break;
  209.     case gs_color_space_index_Separation:
  210.         if ( allow == cs_allow_base )
  211.             return_error(e_rangecheck);
  212.         if ( asize != 3 )
  213.             return_error(e_rangecheck);
  214.         check_type(*pcsa, t_name);
  215.         check_proc(pcsa[2]);
  216.         code = cspace_param(pcsa + 1, (gs_color_space *)&pcs->params.separation.alt_space, pcprocs, cs_allow_base);
  217.         if ( code < 0 )
  218.             return code;
  219.         pcprocs->special.separation.layer_name = pcsa[0];
  220.         pcprocs->special.separation.tint_transform = pcsa[2];
  221.         pcs->type = &gs_color_space_type_Separation;
  222.         break;
  223.     case gs_color_space_index_Indexed:
  224.         if ( allow == cs_allow_base )
  225.             return_error(e_rangecheck);
  226.         if ( asize != 3 )
  227.             return_error(e_rangecheck);
  228.         check_type(pcsa[1], t_integer);
  229.         if ( pcsa[1].value.intval < 0 || pcsa[1].value.intval > 4095 )
  230.             return_error(e_rangecheck);
  231.         pcs->params.indexed.hival = pcsa[1].value.intval;
  232.         /* We must get the base space now, rather than later, */
  233.         /* so we can check the length of the table against */
  234.         /* the num_components of the base space. */
  235.         code = cspace_param(pcsa, (gs_color_space *)&pcs->params.indexed.base_space, pcprocs, cs_allow_base);
  236.         if ( code < 0 )
  237.             return code;
  238.         if ( r_has_type(&pcsa[2], t_string) )
  239.         {    check_read(pcsa[2]);
  240.             if ( r_size(&pcsa[2]) !=
  241.                   (pcs->params.indexed.hival + 1) *
  242.                   pcs->params.indexed.base_space.type->num_components
  243.                )
  244.                 return_error(e_rangecheck);
  245.             pcs->params.indexed.lookup.table =
  246.                 pcsa[2].value.const_bytes;
  247.             pcs->params.indexed.use_proc = 0;
  248.             make_null(&pcprocs->special.index_proc);
  249.         }
  250.         else
  251.         {    check_proc(pcsa[2]);
  252.             pcs->params.indexed.lookup.proc =
  253.                 null_indexed_lookup_proc;
  254.             pcs->params.indexed.use_proc = 1;
  255.             pcprocs->special.index_proc = pcsa[2];
  256.         }
  257.         pcs->type = &gs_color_space_type_Indexed;
  258.         break;
  259.     case gs_color_space_index_Pattern:
  260.         if ( allow != cs_allow_all )
  261.             return_error(e_rangecheck);
  262.         switch ( asize )
  263.         {
  264.         case 0:        /* no base space */
  265.             pcs->params.pattern.has_base_space = 0;
  266.             break;
  267.         default:
  268.             return_error(e_rangecheck);
  269.         case 1:
  270.             pcs->params.pattern.has_base_space = 1;
  271.             code = cspace_param(pcsa,
  272.               (gs_color_space *)&pcs->params.pattern.base_space,
  273.               pcprocs, cs_allow_paint);
  274.             if ( code < 0 )
  275.                 return code;
  276.         }
  277.         pcs->type = &gs_color_space_type_Pattern;
  278.         break;
  279.     default:
  280.         return_error(e_typecheck);
  281.     }
  282.     return 0;
  283. }
  284.